package models

import (
	"gin-AssetManagement/inits/casbininit"
	"strings"
)

var e = casbininit.Ecasbin

// DelCasbinByRolesId 删除角色ID所有规则
func DelCasbinByRolesId(rolesId string) error {
	_, err := e.RemoveFilteredPolicy(0, rolesId)
	if err != nil {
		return err
	}
	return nil
}

// AddCasbin 添加角色和菜单对应规则
func AddCasbin(rolesId string, menuIDs []int) error {
	removed := make([]string, 0)
	menus, err := QueryMenusByIds(menuIDs)
	if err != nil {
		return err
	}
	for _, v := range menus {
		removed = append(removed, rolesId, v.URL, v.RequestType)
	}
	rules := splitSlice(removed, 3)
	duplicateRules := Deduplicate(rules)
	areRulesAdded, err := e.AddPolicies(duplicateRules)
	if areRulesAdded == false && err != nil {
		return err
	}
	return nil
}

// splitSlice 把[]string 切片每3个元素就切割，返回一个新的二元[][]string
/*
例如 slice := []string{"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l"}
返回：新的[][]string
[a b c]
[d e f]
[g h i]
[j k l]
*/
func splitSlice(slice []string, size int) [][]string {
	var result [][]string

	for i := 0; i < len(slice); i += size {
		end := i + size

		if end > len(slice) {
			end = len(slice)
		}

		result = append(result, slice[i:end])
	}

	return result
}

// Deduplicate 规则去重复
func Deduplicate(input [][]string) [][]string {
	// 创建一个空的map，用于记录已经出现过的元素
	seen := make(map[string]bool)
	var result [][]string

	// 遍历二维切片中的每个元素
	for _, slice := range input {
		// 将每个元素转换为字符串，并检查该字符串是否已经存在于map中
		str := strings.Join(slice, ",")
		if !seen[str] {
			// 如果该字符串不存在于map中，则将其添加到map中，并将其添加到结果切片中
			seen[str] = true
			result = append(result, slice)
		}
	}

	return result
}
